package com.ccrfid.rmc6.util;

import org.springframework.boot.system.ApplicationHome;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.StringUtils;

import javax.crypto.Cipher;
import java.io.*;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Date;

public class LicenseUtil {
    /**
     * 验证license
     *
     * @return <0  license 验证不通过
     */
    public static int verifyLicense() {
        String licenseContent = getLicenseContent();
        if (licenseContent == null) {
            return -5;  //license file not found
        }
        String originContent = decrypt(licenseContent);
        if (StringUtils.isEmpty(originContent)) {
            return -4;  //license格式错误
        }
        String[] dateArray = originContent.split(",");
        if (dateArray == null || dateArray.length != 2) {
            return -3;  //license格式错误
        }
        Date startTime = DateUtil.parseDateTimeStr(dateArray[0] + " 00:00:01");
        Date stopTime = DateUtil.parseDateTimeStr(dateArray[1] + " 23:59:59");
        if (startTime == null || stopTime == null) {
            return -2;  //license格式错误
        }
        Date now = new Date();
        if (now.after(startTime) && now.before(stopTime)) {
            return 0;   //license验证通过
        } else {
            return -1;  //license过期
        }
    }

    private static final String publicKeyBase64 =
            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmjmZYGsRRFJMBszfi+YtyyyIun4rWSpk\n" +
                    "zkJa9JX0fgU23vkDyte4tT0lyxMXJkKFhbJDkH4LPsIY02yUWgeF1WEqpYTYKuRg9YWw2au4Kr0m\n" +
                    "GF79Ipq61oETRXLtCt4n1VhcUW9FXhmG+MIncQ3zrnF7Cj8faJWOAyMRQT4B2Dlutb3AiSSQb7cJ\n" +
                    "4mxX8MzwA2pkNdfTq0roVgeD4I/lqaoa2q4VQ1Wk3JgYwN9wVq0BF+2LCJ2cJ9zR7mBZWW0VXtGh\n" +
                    "+DBpbiuOn0lhdCwqwaLbBwhYmM5aRPdCuHvEtaa07PpKLwEM9wHxbw6cfOBemNkeIpeK0NG0QJHN\n" +
                    "9toyXwIDAQAB";

    private static PublicKey getPublicKey(String base64)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] keyBytes = Base64.getMimeDecoder().decode(base64);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    //解密
    private static String decrypt(String licenseContent) {
        try {
            PublicKey publicKey = getPublicKey(publicKeyBase64);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            byte[] buf = Base64.getMimeDecoder().decode(licenseContent);
            byte[] decryptBuf = cipher.doFinal(buf);
            return new String(decryptBuf);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    private static String getLicenseContent() {
        StringBuilder stringBuilder = new StringBuilder();
        String path = new ApplicationHome(LicenseUtil.class).getSource().getPath();
        int endIndex = path.lastIndexOf("\\") > 0 ? path.lastIndexOf("\\") : path.lastIndexOf("/");
        String filePath = path.substring(0, endIndex) + "/license";
        File file = new File(filePath);
        BufferedReader reader = null;
        try {
            if (file.exists()) {
                reader = new BufferedReader(new FileReader(file));
            } else {
                ClassPathResource resource = new ClassPathResource("license");
                reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
            }
            String line = null;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
            return stringBuilder.toString();
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }

    }
}
